home *** CD-ROM | disk | FTP | other *** search
- ' EditField
- '
- ' V1.0
- '
- ' (C) 1987 By Tony Elliott
- '
- ' A Multi-purpose Field Editor for QuickBASIC V4.0
- '
- ' Please refer any comments or suggestions to the QuickBASIC
- ' Conference at Programmer's Information Exchange (404) 928-0033
- '
- '
- '
- 'EDITFLD.BAS Module Level Code
-
- DEFINT A-Z
- COMMON SHARED /editfld/ row, col, ucase, minval!, maxval!, justify, padchar, keystat, kfg, kbg, krow, kcol, sfg, sbg, dfg, dbg, insmode, nul, Alarm
-
- SUB EditField (old$, ed$, format$, retflag%) STATIC
-
- Initialize:
- retflag = 0 'Reset condition flag from previous calls
- ed$ = old$ 'Make old$ the string to edit
- comp$ = old$ 'Keep an original copy (before case conversions)
- fldlen = LEN(format$) 'Set fldlen to the length of format$.
- IF insmode <> 0 THEN 'If insert mode is on then
- insert = -1 'change value for call to setkbd.
- LOCATE , , , 1, 7 'Change cursor to block
- ELSE 'If insert is off then
- insert = 0 'change variable for call
- LOCATE , , , 6, 7 'and change cursor to flat line.
- END IF
- CALL setkbd(insert, 0, 0, 0) 'Set insert mode.
-
- 'Set Defaults
- IF row = 0 AND col = 0 THEN row = CSRLIN: col = POS(0) 'Use current cursor location.
- IF sfg = 0 AND sbg = 0 THEN sfg = 0: sbg = 7 'and background colors.
- IF dfg = 0 AND dbg = 0 THEN dfg = 7: dbg = 0 'when exiting the routine.
- IF padchar = 0 THEN padchar = 32
- IF (krow = 0 AND kcol = 0) OR (kfg = 0 AND kbg = 0) THEN keystat = 0 'For keystat, turn it off.
-
- GOSUB ChangeCase 'Makes initial case conversion / UPCASE flag
- fieldreset = 0 'Use sfg,sbg colors
- IF LEFT$(format$, 1) = "\" THEN 'Checks the type of data to be
- ftype = 1 'input.
- END IF
- 'If ftype=1 then it is a text field
- IF LEFT$(format$, 1) = "#" THEN 'If ftype=2 then it is a numeric field
- ftype = 2
- IF ucase <> 0 THEN insert = -1
- IF VAL(old$) = 0 THEN 'Make sure that no string data was
- old$ = "" 'accidently passed in old$
- comp$ = ""
- ELSE
- old$ = STR$(VAL(old$)) 'If numeric mode, make sure a numeric
- comp$ = old$ 'VALUE (not alphabetic characters)
- END IF 'was passed in old$.
- IF maxval! = 0 THEN 'If no value was supplied for maxval!,
- decloc = INSTR(format$, ".") 'find the location of the decimal.
- IF decloc = 0 THEN 'If no decimal, then set maxval! to
- maxval! = 10 ^ LEN(format$) - 1 '10 to the power of the number of digits
- ELSE 'in format$ minus 1, or if there is a decimal,
- maxval! = 10 ^ (decloc - 1) - 1 'to the power of the number of digits to the
- END IF 'left of the decimal minus 1.
- END IF
- END IF
-
- IF ftype = 0 THEN 'If format$ was invalid
- stat$ = "** Invalid FORMAT$ ! Cannot Process field! **"
- CALL StatLine(stat$, stat) 'Display stat$ on line 25
- GOSUB Alarm 'Sound alarm
- retflag = 99 'Set flag to indicate error.
- GOSUB ResetVar 'Reset argument variables
- EXIT SUB 'Exit subprogram
- END IF
- GOSUB FormatField 'Display field in required format.
-
- Position:
- GOSUB DisplayField 'Display field contents in selected colors
- 'and format.
- Strobe:
- inp$ = INKEY$ 'Strobe keyboard for input
- GOSUB DisplayStatus 'display INS, CAPS & NUM Lock status
- IF inp$ = "" THEN GOTO Strobe 'Nothing here, try again.
-
- IF stat = 1 THEN 'If there is a message on the status
- CALL StatLine("", stat) 'line... turn it off.
- END IF
-
- IF LEN(inp$) = 2 THEN GOTO ExtendedKeys 'Check to see if extended key was pressed
-
- char = ASC(inp$) 'It's easier to work with numbers using CASE.
- SELECT CASE char 'Checks for standard characters
- CASE 13 'Check for return.
- GOTO ExitSub
-
- CASE 27 'check for ESC key. If pressed once and
- IF ftype = 1 THEN 'the field has been changed from its
- IF comp$ <> ed$ AND abort = 0 THEN 'original value, the original value will
- ed$ = old$ 'be restored. If pressed a second time,
- curpos = LEN(ed$): abort = -1 'the routine will be exited and an abort
- GOTO Position 'flag will be set.
- ELSE
- retflag = 1 'Set retflag to indicating an abort,
- GOSUB FormatField 'Reset the field display,
- GOSUB ResetVar 'reset argument variables and
- EXIT SUB 'exit the routine.
- END IF
- ELSE
- firstnum = 0
- IF VAL(old$) <> VAL(ed$) THEN 'This handles "numeric only" data if the
- IF VAL(old$) > 0 THEN 'ESC was pressed
- ed$ = old$ 'Restore original value
- GOSUB FormatField 'Use special numeric formatting.
- GOTO Position 'Go back and display field.
- ELSE
- LOCATE row, col 'If nothing was passed in old$,
- PRINT SPC(fldlen); 'and no current value, erase the
- GOTO Position 'field.
- END IF
- ELSE
- retflag = 1 'ESC was pressed a second consecutive
- GOSUB FormatField 'time. Set retflag to indicate an "abort",
- GOSUB ResetVar 'reset argument variables
- EXIT SUB 'and exit the routine.
- END IF
- END IF
-
- CASE 8 'Check for backspace key.
- IF LEN(ed$) = 0 OR curpos = 0 THEN 'If on an empty field...
- GOSUB Alarm 'sound alarm and go back for
- GOTO Strobe 'more input.
- END IF
- IF LEN(ed$) > 1 THEN 'If ed$ is longer than one character then
- ed$ = LEFT$(ed$, curpos - 1) + RIGHT$(ed$, LEN(ed$) - (curpos))
- curpos = curpos - 1 'Move cursor to left one character.
- ELSE
- ed$ = "" 'If ed$ is one character long then
- curpos = 0 'erase it and reset the cursor position.
- END IF
-
- CASE ELSE 'If any other key was pressed
- IF ftype = 1 THEN 'and in the text entry mode, check
- IF ASC(inp$) < 32 OR ASC(inp$) > 128 THEN 'if character is standard alphabetic.
- GOSUB Alarm 'Nope! Sound bell and display a message
- stat$ = "** Invalid Character! **" 'on line 25.
- CALL StatLine(stat$, stat)
- GOTO Strobe 'Go back and try again
- ELSE
- GOSUB ChangeCase 'Character passed test.. Now make the
- END IF 'proper case conversion.
- ELSE
- IF ASC(inp$) <> 46 AND (ASC(inp$) < 48 OR ASC(inp$) > 57) THEN '0-9 and "." (decimal).
- GOSUB Alarm 'Uh oh.. Gotcha
- stat$ = "Only Numeric Input is Allowed!" 'Sound the bell and display the
- CALL StatLine(stat$, stat) 'status message on line 25.
- GOTO Strobe 'Go back and try again.
- END IF
- IF ucase <> 0 AND firstnum = 0 THEN 'If in the numeric mode and ucase
- ed$ = inp$ 'is non-zero and a key has not been
- firstnum = 1 'pressed since the routine has been
- curpos = 1 'called, clear the field, set ed$ to
- GOSUB DisplayField 'the key pressed, set the cursor to the
- GOTO Strobe 'begin
- END IF
- END IF
-
- IF LEN(ed$) = fldlen AND (insert OR curpos = fldlen) THEN 'Is the field at its maximum
- GOSUB Alarm 'length? Yes, sound bell
- stat$ = "** String is at Maximum Length! **" 'display status message
- CALL StatLine(stat$, stat)
- GOTO Strobe 'Go back and try again
- END IF
-
- IF insert THEN 'In the insert mode, add inp$ at cursor position moving
- ed$ = LEFT$(ed$, curpos) + inp$ + RIGHT$(ed$, LEN(ed$) - (curpos)) 'everthing to the right of the cursor
- ELSE 'to the right one space.
- IF curpos = LEN(ed$) THEN 'If at the end of the field and in the
- ed$ = ed$ + inp$ 'overwrite mode, add inp$ to the end of
- ELSE 'ed$.
- MID$(ed$, curpos + 1) = inp$ 'If not at the end of the field, replace
- END IF 'character at the cursor's position with
- END IF 'inp$.
- curpos = curpos + 1 'Move over one space.
- IF curpos = fldlen THEN 'If cursor is past the end of the field
- curpos = fldlen - 1 'move it back.
- END IF
- END SELECT
- abort = 0 'Reset the ESC flag
- GOTO Position
-
-
- ExtendedKeys: 'Process the Extended Keys
- exkey = ASC(RIGHT$(inp$, 1)) 'Put extended key code in exkey.
- SELECT CASE exkey
- CASE 83 'Delete Key -- Deletes character at
- IF curpos < LEN(ed$) THEN 'cursor position.
- ed$ = LEFT$(ed$, curpos) + RIGHT$(ed$, LEN(ed$) - (curpos + 1))
- ELSE 'If cursor is not inside the field
- GOSUB Alarm 'then sound bell.
- END IF
-
- CASE 75 'Left Arrow -- Cursor left one
- curpos = curpos - 1 'character. Stop at first character
- IF curpos < 0 THEN curpos = 0 'in field
-
- CASE 77 'Cursor-Right
- IF curpos < LEN(ed$) AND curpos < fldlen - 1 THEN 'Don't move past the right end of the
- curpos = curpos + 1 'current string or outside of the defined field
- END IF
-
- CASE 82 'Insert Key. Acutal changing of the
- IF insert THEN 'If insert is on
- LOCATE , , , 1, 7 'change cursor to a block.
- ELSE 'if not,
- LOCATE , , , 6, 7 'change it to a flat line
- END IF
-
- CASE 71 'Home Key -- Position cursor on
- curpos = 0 'first character in field.
-
- CASE 79 'End Key -- Cursor to last
- curpos = LEN(ed$) 'character in field.
- IF curpos = fldlen THEN 'Don't let cursor go ouside
- curpos = fldlen - 1 'of the field
- END IF
-
- CASE 119 'Ctrl-Home -- Deletes contents of
- ed$ = "" 'current field.
- curpos = 0
-
- CASE 116 'Ctrl-Cursor Right - Move cursor to the
- wordloc = INSTR(curpos + 1, ed$, " ") 'right one word.
- IF wordloc > 0 THEN curpos = wordloc 'Space is the only valid delimeter.
-
- CASE 115 'Ctrl-Left Arrow - Word Left.
- FOR char = curpos TO 1 STEP -1 'Start looking for a space from the current
- word$ = MID$(ed$, char, 1) 'cursor position to the beginning of the field.
- IF word$ = " " AND char < curpos THEN 'If found, the position is flagged in the
- EXIT FOR '"char" variable. Exit the FOR loop.
- END IF 'If not found, try the next character.
- NEXT char 'Position cursor at flagged location. If nothing
- curpos = char 'was found, it will be at the beginning of the field.
-
- CASE 117 'Cntrl-End -Clear from cursor to end of field
- ed$ = LEFT$(ed$, curpos) 'Left trunctuate ed$ at cursor position
- GOSUB DisplayField 'Redisplay field
-
- CASE ELSE 'If any other extended key was pressed,
- retflag = exkey 'return its code in retflag.
- GOTO ExitSub 'This is signal to exit the routine.
-
- END SELECT
- GOTO Position
-
-
- ExitSub:
- IF nul <> 0 AND ((ftype = 1 AND ed$ = "") OR (ftype = 2 AND VAL(ed$) = 0)) THEN
- stat$ = "*** An Entry is Required. Press ESC to Abort ***"
- CALL StatLine(stat$, stat) 'If ed$ is nul and it is not allowed,
- GOSUB Alarm 'display a message, sound the bell and
- GOTO Position 'return for input.
- END IF
-
- IF ftype = 2 THEN
- IF (VAL(ed$) > maxval! OR VAL(ed$) < minval!) THEN
- stat$ = "*** Acceptable Values are" + STR$(minval!) + " -" + STR$(maxval!) + ". Please Re-enter. ***"
- CALL StatLine(stat$, stat) 'If value of ed$<minval! or >maxval! then
- GOSUB Alarm 'sound the bell..
- ed$ = old$ 'restore ed$ to the original value
- GOSUB FormatField 'Re-display the original value in the
- GOTO Position 'correct format and begin again.
- END IF
- END IF
- fieldreset = 1 'Display field using dfg,dbg colors.
- GOSUB FormatField 'Retrieve the formatted output.
- IF ftype = 1 THEN 'If in the text entry mode, format the text
- SELECT CASE justify 'obeying the justify argument.
- CASE 1 'Left Justify
- ed$ = LEFT$(ed$ + STRING$(fldlen, 32), fldlen)
-
- CASE 2 'Right justify
- ed$ = RIGHT$(STRING$(fldlen, 32) + ed$, fldlen)
-
- CASE 3 'Center text within the width of
- IF LEN(ed$) < fldlen - 2 THEN 'format$. Length must be at
- temp$ = STRING$(fldlen, 32) 'least 2 characters less than
- fldpos = (fldlen - LEN(ed$)) / 2 'format$.
- MID$(temp$, fldpos, LEN(ed$)) = ed$
- ed$ = temp$
- END IF
-
- CASE ELSE 'If zero or anything else, do nothing.
- END SELECT
- GOSUB FormatField 'Re-display the formatted field
- ELSE
- IF justify <> 0 THEN 'If in the numeric mode an justify is
- ed$ = STR$(VAL(ed$)) 'set to a non-zero, remove the
- END IF 'print using format from ed$.
- END IF
- GOSUB ResetVar 'Reset argument variables
- EXIT SUB 'Bye-bye
-
- DisplayField:
- GOSUB ChangeCase 'Make case conversion.
- COLOR sfg, sbg 'Use "selected" colors
- LOCATE row, col, 0 'Position cursor
- IF ftype = 1 THEN 'Text print routine
- PRINT USING format$; ed$ + STRING$(fldlen, padchar);
- LOCATE row, col + LEN(ed$)
- ELSE
- PRINT LEFT$(ed$ + STRING$(fldlen, 32), fldlen)'Numeric print routine
- END IF
- LOCATE row, col + curpos, 1
- RETURN
-
- FormatField:
- num$ = ""
- LOCATE row, col, 0 'Position cursor & turn off
- GOSUB ChangeCase 'Change to proper case
- IF fieldreset = 1 OR retflag = 1 THEN 'Set color based on FIELDRESET.
- COLOR dfg, dbg 'IF 1 then the routine is preparing
- ELSE 'exit, and if 0 the routine is
- COLOR sfg, sbg 'initializing.
- END IF
- IF ftype = 1 THEN 'Display text using format$
- PRINT USING format$; ed$
- ELSE
- IF VAL(ed$) = 0 THEN 'If ed$ has no numeric value then just
- PRINT SPC(fldlen); 'print spaces on the screen so entering
- num$ = " " 'new data is easier.
- ELSE
- PRINT USING format$; VAL(ed$) 'Print numeric data using format$.
- IF num$ = "" THEN
- FOR char = col TO col + fldlen - 1 'Read formated numeric display
- num$ = num$ + CHR$(SCREEN(row, char)) 'from screen into num$ for proper
- NEXT char 'on screen editing
- ed$ = num$ 'Assign ed$ with data retrieved from
- END IF 'display.
- END IF
- END IF
- IF insmode THEN 'If insert is on, position cursor at beginning
- curpos = 0 'of field. If off, position cursor at end
- ELSE 'of field (personal preference).
- curpos = LEN(ed$)
- IF curpos = fldlen THEN 'Don't let cursor wander outside
- curpos = fldlen - 1 'of the field
- END IF
- END IF
- LOCATE , , 1 'Make sure cursor is on.
- RETURN
-
- ChangeCase:
- IF ucase = 1 THEN 'Convert to upper case
- ed$ = UCASE$(ed$)
- inp$ = UCASE$(inp$)
- comp$ = UCASE$(comp$)
- ELSEIF ucase = 2 THEN 'Convert to lower case
- ed$ = LCASE$(ed$)
- inp$ = LCASE$(inp$)
- comp$ = LCASE$(comp$)
- END IF
- RETURN
-
- DisplayStatus:
- kstat$ = "" 'Nul the Keyboard status $
- CALL GetKbd(insert, caps, numlk, scrl) 'Get keyboard status.
- IF keystat = 0 THEN RETURN 'If keystat is off, return
- IF insert THEN kstat$ = "INS" ELSE kstat$ = "OVW" 'Create the key status display.
- IF caps THEN kstat$ = kstat$ + "CAP" ELSE kstat$ = kstat$ + " "
- IF numlk THEN kstat$ = kstat$ + "NUM" ELSE kstat$ = kstat$ + " "
- CALL CalcAttr(kfg, kbg, attr) 'Calculate the color attribute. (ADVBAS or PROBAS)
- CALL XqPrint(kstat$, krow, kcol, attr, 0) 'Display it. (ADVBAS)
- 'CALL XqPrint(kstat$, krow, kcol, attr, 0, 0) 'Display it (PROBAS)
- RETURN
-
- ResetVar:
- row = 0: col = 0 'Reset variables for routine
- RETURN 'exit.
-
- Alarm:
- IF noise = 0 THEN 'Sound of error alarm .. Change to
- BEEP 'SOUND 1000,1:SOUND 1500,1:SOUND 1000,1
- END IF 'if you don't like the regular ole "BEEP"
- RETURN
-
- END SUB
-
-